package com.example.guava.ratelimiter.aop;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * IP拦截
 * @author zhouxuan
 * @date 2020/6/11 16:50
 */
@Aspect
@Component
@Slf4j
public class IpLimiterAspect {

    Cache<String, RateLimiter> cache = CacheBuilder.newBuilder().maximumSize(1000).build();

    @Pointcut(value = "execution(* com.example.guava.ratelimiter.controller.*.*(..))")
    public void checkPointCut() {

    }

    @ResponseBody
    @Around(value = "checkPointCut()")
    public Object aroundNotice(ProceedingJoinPoint pjp) throws Throwable {
        //获取目标方法的签名
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        //获取目标方法
        String ip = request.getRemoteAddr();

        RateLimiter limiter = cache.getIfPresent(ip);
        if (null == limiter) {
            limiter = RateLimiter.create(100);
            cache.put(ip, limiter);
        }
        if (!limiter.tryAcquire(1, 10, TimeUnit.MILLISECONDS)) {
            System.out.println(new Date() + "ip失败" + "----" + ip);
        }
        else {
            System.out.println(new Date() + "ip成功" + "----" + ip);
        }
        return pjp.proceed();
    }
}
